package com.netty.server.handler;

import com.netty.server.base.ConnectionAttr;
import com.netty.server.base.ConnectionGroup;
import com.netty.server.cmd.ByteResCmd;
import com.netty.server.cmd.LoginCmd;
import com.netty.server.processor.UpProcessor;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Objects;

/**
 * 登录处理器,处理客户端登录事件
 *
 * @author: 王霄
 * @date: 2022/1/17 14:07
 **/
@Slf4j
public class LoginHandler extends MessageToMessageDecoder<LoginCmd> {

    private final UpProcessor upProcessor;

    private final ConnectionGroup connectionGroup;

    public LoginHandler(UpProcessor upProcessor, ConnectionGroup connectionGroup) {
        this.upProcessor = upProcessor;
        this.connectionGroup = connectionGroup;
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, LoginCmd loginCmd, List<Object> list) {
        log.info(String.format("处理客户端登录事件, mac:[%S], remoteAddress:[%s]",
                loginCmd.getMac(), ctx.channel().remoteAddress()));
        //进行登录,异步执行,监听登录结束后将结果响应给客户端
        upProcessor.login(loginCmd)
                .whenComplete((r, e) -> {
                    ByteResCmd.Code code;
                    if (Objects.equals(r, true)) {
                        log.info(String.format("客户端登录成功, mac:[%S], remoteAddress:[%s]",
                                loginCmd.getMac(), ctx.channel().remoteAddress()));
                        //将唯一标识注入通道
                        ctx.channel().attr(ConnectionAttr.MAC).set(loginCmd.getMac());
                        connectionGroup.register(ctx.channel());
                        code = ByteResCmd.Code.OK;
                    } else {
                        log.info(String.format("客户端登录失败, mac:[%S], remoteAddress:[%s]",
                                loginCmd.getMac(), ctx.channel().remoteAddress()), e);
                        code = ByteResCmd.Code.FAIL;
                    }
                    //将结果发送给客户端
                    ByteResCmd resCmd = ByteResCmd.build(loginCmd.getOrigin(), code);
                    ctx.channel().writeAndFlush(resCmd);
                });
    }
}
